
package com.insigma.business.qrcode.soldier._provider.impl;


import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

import com.insigma.business.qrcode.common.dao.CommonAdminAreaDO;
import com.insigma.business.qrcode.common.service.CommonAdminAreaService;
import com.insigma.business.qrcode.common._provider.CommonRepresentationRecordProvider;
import com.insigma.business.qrcode.common.template.BasePagingResponse;
import com.insigma.business.qrcode.common.util.BizCheckUtil;
import com.insigma.business.qrcode.common.util.BizException;
import com.insigma.business.qrcode.common.util.ResponseUtils;
import com.insigma.business.qrcode.common.vo.BaseDeleteRequest;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.common.vo.ProcessStatusEnum;
import com.insigma.business.qrcode.common.vo.RepresentationTypeEnum;
import com.insigma.business.qrcode.soldier._provider.PlacementInfoProvider;
import com.insigma.business.qrcode.soldier.dto.*;
import com.insigma.business.qrcode.soldier.dto.gov.BaseProviderImpl;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.soldier.entity.*;
import com.insigma.business.qrcode.common.dto.ErrorCodeEnum;
import com.insigma.business.qrcode.soldier.request.*;
import com.insigma.business.qrcode.soldier.service.*;
import com.insigma.business.qrcode.common.converter.PlacementInfoProviderConverter;
import com.insigma.business.qrcode.common.converter.PlacementPositionInfoProviderConverter;
import com.insigma.business.qrcode.common.converter.PlacementSoldierInfoProviderConverter;
import com.insigma.business.qrcode.soldier.util.RequestSetUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.insigma.business.qrcode.common.service.GovOrgService;
import org.springframework.util.CollectionUtils;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;


@Slf4j
@Service
@Component("placementInfoProvider")
public class PlacementInfoProviderImpl extends BaseProviderImpl implements PlacementInfoProvider {

    @Autowired
    private PlacementInfoService placementInfoService;

    @Autowired
    private PlacementBatchService placementBatchService;

    @Autowired
    private GovOrgService govOrgService;

    @Autowired
    private CommonAdminAreaService commonAdminAreaService;

    @Autowired
    private PlacementSoldierAspirationService placementSoldierAspirationService;

    @Autowired
    private PlacementSoldierInfoService placementSoldierInfoService;

    @Autowired
    private PlacementSoldierAspirationResultService placementSoldierAspirationResultService;

    @Autowired
    private PlacementPositionInfoService placementPositionInfoService;

    @Autowired
    private PlacementThroughTrainApplyInfoService placementThroughTrainApplyInfoService;

    @Autowired
    private CommonRepresentationRecordProvider commonRepresentationRecordProvider;



    @Override
    public BaseResponse<PlacementStatsInfoDTO> statPlacement(SimpleApiRequest request) {
        log.info("查询统计信息, {}", request);
        BizCheckUtil.checkNotNull(request, "请求不能为空");
        List<GovOrgDO> govList = govOrgService.listByEmployeeId(request.getEmployeeId());
        BizCheckUtil.checkIsTrue(!CollectionUtils.isEmpty(govList), "员工错误");
        String adminAreaCode = govList.get(0).getLeafAdminAreaId();
        PlacementStatsInfoDTO result = new PlacementStatsInfoDTO();
        PlacementInfoDO placementInfoDO = placementInfoService.getByAdminAreaCode(adminAreaCode);
        if (placementInfoDO == null) {
            return ResponseUtils.buildSuccessResponse(result);
        }


        PlacementSoldierInfoBSearcher soldierInfoBSearcher = new PlacementSoldierInfoBSearcher(1, 10);
        soldierInfoBSearcher.setPlacementId(placementInfoDO.getId());
        result.setTotalNum(placementSoldierInfoService.count(soldierInfoBSearcher));

        PlacementBatchDO tBatchDO = placementBatchService.getByPlacementIdAndType(placementInfoDO.getId(), PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        soldierInfoBSearcher.setBatchId(tBatchDO.getId());
        result.setThroughTrainNum(placementSoldierInfoService.countSuccess(soldierInfoBSearcher));
        result.setUnifiedApplyNum(result.getTotalNum() - result.getThroughTrainNum());

        PlacementBatchDO uBatchDO = placementBatchService.getByPlacementIdAndType(placementInfoDO.getId(), PlacementBatchTypeEnum.UNIFIED.name());
        soldierInfoBSearcher.setBatchId(uBatchDO.getId());
        soldierInfoBSearcher.setIsPlacement(true);
        result.setUnifiedSccNum(placementSoldierInfoService.count(soldierInfoBSearcher));
        result.setOfflineNum(result.getTotalNum() - result.getThroughTrainNum() - result.getUnifiedSccNum());


        PlacementBatchDO thoughtBatch = placementBatchService.getByPlacementIdAndType(placementInfoDO.getId(), PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        PlacementSoldierAspirationBSearcher aSearcher = new PlacementSoldierAspirationBSearcher(1, 10);
        aSearcher.setBatchId(thoughtBatch.getId());
        Integer count = placementSoldierAspirationService.count(aSearcher);
        result.setThroughTrainApplyNum(count);
        aSearcher.setStatus(ProcessStatusEnum.SUCCESS.name());
        result.setThroughTrainPassNum(placementSoldierAspirationService.count(aSearcher));
        aSearcher.setStatus(ProcessStatusEnum.REJECT.name());
        result.setThroughTrainRejectNum(placementSoldierAspirationService.count(aSearcher));
        result.setThroughTrainSucNum(result.getThroughTrainNum());
        return ResponseUtils.buildSuccessResponse(result);
    }


    @Override
    public BasePagingResponse<List<PlacementInfoDTO>> searchPlacementInfo(final PlacementInfoSearchRequest searchRequest) {

        final BasePagingResponse<List<PlacementInfoDTO>> basePagingResponse = new BasePagingResponse<>();
        serviceTemplate.execute(basePagingResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(searchRequest, "查询分页PlacementInfo的请求参数不能为空");
            }

            @Override
            public void executeService() {
                String adminAreaCodeOfEmploy = govOrgService.getAdminAreaCodeOfEmploy(searchRequest.getEmployeeId());
                searchRequest.setAdminAreaCode(adminAreaCodeOfEmploy);

                final PlacementInfoBSearcher placementInfoBSearcher = PlacementInfoProviderConverter.convertRequestSO2Searcher(searchRequest);
                final List<PlacementInfoDO> placementInfoDOList = placementInfoService.search(placementInfoBSearcher);
                final List<PlacementInfoDTO> placementInfoDTOList = PlacementInfoProviderConverter.convertResponseDOList2DTOList(placementInfoDOList);
                List<PlacementInfoDTO> result = new ArrayList<>();
                for (PlacementInfoDTO placementInfoDTO : placementInfoDTOList) {
                    result.add(buildPlacementInfoDTO(placementInfoDTO.getId()));
                }
                ResponseUtils.buildSuccessPagingResponse(basePagingResponse, result, searchRequest, placementInfoBSearcher.getTotalCount());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.PLACEMENT_INFO_SEARCH;
            }
        });

        return basePagingResponse;
    }



    @Override
    public BaseResponse<PlacementInfoDTO> getPlacementInfo(final BaseGetRequest baseGetRequest) {

        final BaseResponse<PlacementInfoDTO> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(baseGetRequest, "获取单条PlacementInfo的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) baseGetRequest.getId(), "id不能为空");
            }

            @Override
            public void executeService() {
                String id = (String) baseGetRequest.getId();
                final PlacementInfoDTO remoteObj = buildPlacementInfoDTO(id);

                ResponseUtils.setupSuccessResponse(baseResponse, remoteObj);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.PLACEMENT_INFO_GET;
            }
        });
        return baseResponse;
    }

    private PlacementInfoDTO buildPlacementInfoDTO(String id) {
        final PlacementInfoDO placementInfoDO = placementInfoService.get(id);
        final PlacementInfoDTO remoteObj = PlacementInfoProviderConverter.convertResponseDO2DTO(placementInfoDO);

        PlacementBatchDO tt = placementBatchService.getByPlacementIdAndType(id, PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        remoteObj.setThroughTrainStartDatetime(tt.getStartDatetime());
        remoteObj.setThroughTrainEndDatetime(tt.getPublishDatetime());

        PlacementBatchDO uu = placementBatchService.getByPlacementIdAndType(id, PlacementBatchTypeEnum.UNIFIED.name());
        remoteObj.setUnifiedStartDatetime(uu.getStartDatetime());
        remoteObj.setUnifiedApplyStartDatetime(uu.getApplyStartDatetime());
        remoteObj.setUnifiedApplyEndDatetime(uu.getApplyEndDatetime());
        remoteObj.setPublishDatetime(uu.getPublishDatetime());

        PlacementBatchDO off = placementBatchService.getByPlacementIdAndType(id, PlacementBatchTypeEnum.OFFLINE.name());
        remoteObj.setOfflineApplyEndDatetime(off.getApplyEndDatetime());

        PlacementBatchDO currentBatch = placementBatchService.getCurrentBatch(id);
        if (currentBatch != null) {
            remoteObj.setNowProcess(currentBatch.getType());
            remoteObj.setCanApply(currentBatch.getCanApply());
        }
        return remoteObj;
    }


    @Transactional
    @Override
    public BaseResponse<String> insertPlacementInfo(final PlacementInfoInsertRequest insertRequest) {


        BizCheckUtil.checkNotNull(insertRequest, "新增PlacementInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(insertRequest.getEmployeeId(), "员工不能为空");
        BizCheckUtil.checkNotNull(insertRequest.getThroughTrainStartDatetime(), "时间不能为空");
        BizCheckUtil.checkNotNull(insertRequest.getThroughTrainEndDatetime(), "时间不能为空");
        BizCheckUtil.checkNotNull(insertRequest.getUnifiedStartDatetime(), "时间不能为空");
        BizCheckUtil.checkNotNull(insertRequest.getUnifiedApplyStartDatetime(), "时间不能为空");
        BizCheckUtil.checkNotNull(insertRequest.getUnifiedApplyEndDatetime(), "时间不能为空");

        List<GovOrgDO> govList = govOrgService.listByEmployeeId(insertRequest.getEmployeeId());
        BizCheckUtil.checkIsTrue(!CollectionUtils.isEmpty(govList), "员工错误");
        String adminAreaCode = govList.get(0).getLeafAdminAreaId();

        BizCheckUtil.checkIsTrue(insertRequest.getUnifiedStartDatetime().compareTo(insertRequest.getThroughTrainEndDatetime()) > 0, "时间重叠");

        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        BizCheckUtil.checkIsTrue(alivePlacement == null, "已存在");

        PlacementInfoDO placementInfoDO = addPlacement(adminAreaCode, insertRequest);
        addThroughTrain(placementInfoDO, insertRequest);
        addUnified(placementInfoDO, insertRequest);
        addOffline(placementInfoDO, insertRequest);

        return ResponseUtils.buildSuccessResponse(placementInfoDO.getId());
    }


    private void addOffline(PlacementInfoDO placementInfoDO, PlacementInfoInsertRequest insertRequest) {
        PlacementBatchDO batchDO = new PlacementBatchDO();
        batchDO.setPlacementId(placementInfoDO.getId());
        batchDO.setType(PlacementBatchTypeEnum.OFFLINE.name());
        batchDO.setSeqNo(2);
        batchDO.setStartDatetime(insertRequest.getOfflineStartDatetime());
        batchDO.setApplyStartDatetime(insertRequest.getOfflineApplyStartDatetime());
        batchDO.setApplyEndDatetime(insertRequest.getOfflineApplyEndDatetime());
        batchDO.setPublishDatetime(insertRequest.getPublishDatetime());
        batchDO.setPublished(false);
        batchDO.setCanApply(true);
        batchDO.setStatus(ProcessStatusEnum.DEALING.name());
        RequestSetUtils.setCreatorInfo(batchDO, insertRequest);
        placementBatchService.insert(batchDO);
    }

    private void addUnified(PlacementInfoDO placementInfoDO, PlacementInfoInsertRequest insertRequest) {
        PlacementBatchDO batchDO = new PlacementBatchDO();
        batchDO.setPlacementId(placementInfoDO.getId());
        batchDO.setType(PlacementBatchTypeEnum.UNIFIED.name());
        batchDO.setSeqNo(1);
        batchDO.setStartDatetime(insertRequest.getUnifiedStartDatetime());
        batchDO.setApplyStartDatetime(insertRequest.getUnifiedApplyStartDatetime());
        batchDO.setApplyEndDatetime(insertRequest.getUnifiedApplyEndDatetime());
        batchDO.setPublishDatetime(insertRequest.getPublishDatetime());
        batchDO.setPublished(false);
        batchDO.setCanApply(true);
        batchDO.setStatus(ProcessStatusEnum.DEALING.name());
        RequestSetUtils.setCreatorInfo(batchDO, insertRequest);
        placementBatchService.insert(batchDO);
    }

    private void addThroughTrain(PlacementInfoDO placementInfoDO, PlacementInfoInsertRequest insertRequest) {
        PlacementBatchDO batchDO = new PlacementBatchDO();
        batchDO.setPlacementId(placementInfoDO.getId());
        batchDO.setType(PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        batchDO.setSeqNo(0);
        batchDO.setStartDatetime(insertRequest.getThroughTrainStartDatetime());
        batchDO.setApplyStartDatetime(insertRequest.getThroughTrainStartDatetime());
        batchDO.setApplyEndDatetime(insertRequest.getThroughTrainEndDatetime());
        batchDO.setPublishDatetime(insertRequest.getThroughTrainEndDatetime());
        batchDO.setPublished(false);
        batchDO.setCanApply(true);
        batchDO.setStatus(ProcessStatusEnum.DEALING.name());
        RequestSetUtils.setCreatorInfo(batchDO, insertRequest);
        placementBatchService.insert(batchDO);
    }

    private PlacementInfoDO addPlacement(String adminAreaCode, PlacementInfoInsertRequest insertRequest) {
        PlacementInfoDO placementInfoDO = new PlacementInfoDO();
        placementInfoDO.setName(buildPlacementName(adminAreaCode));
        placementInfoDO.setAdminAreaCode(adminAreaCode);
        placementInfoDO.setPublished(false);
        RequestSetUtils.setCreatorInfo(placementInfoDO, insertRequest);
        placementInfoService.insert(placementInfoDO);
        return placementInfoDO;
    }

    private String buildPlacementName(String adminAreaCode) {
        String dateStr = DateUtil.format(new Date(), "yyyy-MM");
        CommonAdminAreaDO commonAdminAreaDO = commonAdminAreaService.get(adminAreaCode);
        BizCheckUtil.checkNotNull(commonAdminAreaDO, "地区不存在");

        return dateStr + commonAdminAreaDO.getValue() + "安置";
    }


    @Transactional
    @Override
    public BaseResponse<Integer> updatePlacementInfo(final PlacementInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest, "修改PlacementInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");

        PlacementInfoDO placementInfoDO = placementInfoService.get(updateRequest.getId());
        BizCheckUtil.checkNotNull(placementInfoDO, "安置不存在");
        RequestSetUtils.setModifierInfo(placementInfoDO, updateRequest);
        placementInfoService.update(placementInfoDO);

        PlacementBatchDO tt = placementBatchService.getByPlacementIdAndType(updateRequest.getId(), PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        tt.setStartDatetime(updateRequest.getThroughTrainStartDatetime());
        tt.setApplyStartDatetime(updateRequest.getThroughTrainStartDatetime());
        tt.setApplyEndDatetime(updateRequest.getThroughTrainEndDatetime());
        tt.setPublishDatetime(updateRequest.getThroughTrainEndDatetime());
        tt.setPublished(false);
        RequestSetUtils.setModifierInfo(tt, updateRequest);
        placementBatchService.update(tt);

        PlacementBatchDO uu = placementBatchService.getByPlacementIdAndType(updateRequest.getId(), PlacementBatchTypeEnum.UNIFIED.name());
        uu.setStartDatetime(updateRequest.getUnifiedStartDatetime());
        uu.setApplyStartDatetime(updateRequest.getUnifiedApplyStartDatetime());
        uu.setApplyEndDatetime(updateRequest.getUnifiedApplyEndDatetime());
        uu.setPublishDatetime(updateRequest.getPublishDatetime());
        uu.setPublished(false);
        RequestSetUtils.setModifierInfo(uu, updateRequest);
        placementBatchService.update(uu);

        PlacementBatchDO off = placementBatchService.getByPlacementIdAndType(updateRequest.getId(), PlacementBatchTypeEnum.OFFLINE.name());
        off.setStartDatetime(updateRequest.getOfflineStartDatetime());
        off.setApplyStartDatetime(updateRequest.getOfflineStartDatetime());
        off.setApplyEndDatetime(updateRequest.getOfflineApplyEndDatetime());
        off.setPublishDatetime(updateRequest.getOfflineApplyEndDatetime());
        off.setPublished(false);
        RequestSetUtils.setModifierInfo(off, updateRequest);
        placementBatchService.update(off);

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Override
    public BaseResponse<Integer> updateCanApply(PlacementInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest, "修改PlacementInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
        BizCheckUtil.checkNotNull(updateRequest.getCanApply(), "canApply不能为空");

        PlacementInfoDO placementInfoDO = placementInfoService.get(updateRequest.getId());
        BizCheckUtil.checkNotNull(placementInfoDO, "记录不存在！");
        PlacementBatchDO currentBatch = placementBatchService.getCurrentBatch(updateRequest.getId());
        BizCheckUtil.checkNotNull(currentBatch, "暂无批次！");

        currentBatch.setCanApply(updateRequest.getCanApply());
        placementBatchService.update(currentBatch);
        RequestSetUtils.setModifierInfo(currentBatch, updateRequest);
        return ResponseUtils.buildSuccessResponse(0);
    }

    @Transactional
    @Override
    public BaseResponse<Integer> publishPlacement(PlacementInfoUpdateRequest request) {

        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotNull(request.getPublished(), "published不能为空");
        BizCheckUtil.checkNotBlank(request.getId(), "id不能为空");

        PlacementInfoDO placementInfoDO = placementInfoService.get(request.getId());
        placementInfoDO.setPublished(request.getPublished());
        RequestSetUtils.setModifierInfo(placementInfoDO, request);
        placementInfoService.update(placementInfoDO);

        List<PlacementBatchDO> placementBatchDOS = placementBatchService.listByPlacementId(placementInfoDO.getId());
        for (PlacementBatchDO placementBatchDO : placementBatchDOS) {
            placementBatchDO.setPublished(request.getPublished());
            RequestSetUtils.setModifierInfo(placementBatchDO, request);
            placementBatchService.update(placementBatchDO);
        }

        return ResponseUtils.buildSuccessResponse(placementBatchDOS.size());
    }

    @Override
    public BaseResponse<Integer> calculateBatchMatchResult(String batchId) {

        BizCheckUtil.checkNotNull(batchId, "请求不能为空");

        try {
            PlacementBatchDO placementBatchDO = placementBatchService.get(batchId);
            BizCheckUtil.checkNotNull(placementBatchDO, "批次不存在");

            List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(batchId);
            final List<PlacementPositionInfoDTO> positions = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(placementPositionInfoDOS);

            List<PlacementSoldierInfoDO> placementSoldierInfoDOS = placementSoldierInfoService.listAllNotRecruitSoldier(placementBatchDO.getPlacementId());
            final List<PlacementSoldierInfoDTO> soldiers = PlacementSoldierInfoProviderConverter.convertResponseDOList2DTOList(placementSoldierInfoDOS);
            for (PlacementSoldierInfoDTO soldier : soldiers) {
                if (soldier.getExamScore() == null || soldier.getTotalScore() == null) {
                    throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM, "考试分未导入");
                }
            }

            if (CollectionUtils.isEmpty(soldiers) || CollectionUtils.isEmpty(positions)) {
                return ResponseUtils.buildSuccessResponse(0);
            }

            PlacementSoldierInfoProviderConverter.sortListByScore(soldiers);

            Map<String, PlacementPositionInfoDTO> positionMap = positions.stream().map(s -> {
                s.setUsed(placementSoldierAspirationResultService.countByPositionId(s.getId()));
                s.setWaited(0);
                s.setRecruitList(Lists.newArrayList());
                return s;
            }).collect(Collectors.toMap(PlacementPositionInfoDTO::getId, s -> s));

            List<PlacementSoldierInfoDTO> noMatchSoldiers = Lists.newArrayList();
            boolean lastTiedFlag = false;
            Set<PlacementPositionInfoDTO> tiedPositionSet = Sets.newHashSet();
            for (int i = 0; i < soldiers.size(); i++) {
                PlacementSoldierInfoDTO soldierInfoDTO = soldiers.get(i);

                if (!Boolean.TRUE.equals(soldierInfoDTO.getTiedFlag()) && lastTiedFlag) {
                    refreshWaitList(tiedPositionSet);
                    tiedPositionSet = new HashSet<>();
                    lastTiedFlag = false;
                }

                List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.listByIdCardNoAndBatchId(soldierInfoDTO.getIdCardNo(), placementBatchDO.getId());

                if (CollectionUtils.isEmpty(aspirationDOS)) {
                    continue;
                }
                PlacementSoldierAspirationResultDO aspirationResultDO = placementSoldierAspirationResultService.getByIdCardNo(soldierInfoDTO.getIdCardNo());
                if (aspirationResultDO != null) {
                    continue;
                }

                Collections.sort(aspirationDOS, new Comparator<PlacementSoldierAspirationDO>() {
                    @Override
                    public int compare(PlacementSoldierAspirationDO o1, PlacementSoldierAspirationDO o2) {
                        return o1.getSeqNo().compareTo(o2.getSeqNo());
                    }
                });


                boolean matched = false;
                for (PlacementSoldierAspirationDO aspirationDO : aspirationDOS) {
                    PlacementPositionInfoDTO placementPositionInfoDTO = positionMap.get(aspirationDO.getPositionId());
                    if (placementPositionInfoDTO.getUsed() < placementPositionInfoDTO.getQuota()) {
                        if (Boolean.TRUE.equals(soldierInfoDTO.getTiedFlag())) {

                            placementPositionInfoDTO.setWaited(placementPositionInfoDTO.getWaited() + 1);
                            tiedPositionSet.add(placementPositionInfoDTO);
                            lastTiedFlag = true;
                        } else {
                            placementPositionInfoDTO.setUsed(placementPositionInfoDTO.getUsed() + 1);
                        }

                        placementPositionInfoDTO.getRecruitList().add(soldierInfoDTO);
                        matched = true;
                        break;
                    }
                }


                if (!matched) {
                    noMatchSoldiers.add(soldierInfoDTO);
                }
            }

            int i = savePositionResult(positionMap);
            for (PlacementSoldierInfoDTO noMatchSoldier : noMatchSoldiers) {
                log.error("没有匹配志愿：{}, {}", noMatchSoldier.getIdCardNo(), noMatchSoldier.getRealName());
            }


            placementBatchDO.setStatus(ProcessStatusEnum.SUCCESS.name());
            placementBatchDO.setResultDatetime(new Date());
            placementBatchService.update(placementBatchDO);

        } catch (BizException e) {
            commonRepresentationRecordProvider.insertCommonRepresentationRecord(buildScoreError(e.getErrorMsg()));
            throw e;
        }

        return ResponseUtils.buildSuccessResponse(0);
    }

    private void refreshWaitList(Set<PlacementPositionInfoDTO> positionInfoDTOSet) {
        for (PlacementPositionInfoDTO positionInfoDTO : positionInfoDTOSet) {
            int i = positionInfoDTO.getUsed() + positionInfoDTO.getWaited();
            if (positionInfoDTO.getQuota() < i) {
                log.error("志愿匹配需要人工解决：{}", positionInfoDTO);
                log.error("志愿匹配需要人工解决,人员列表：{}", positionInfoDTO.getRecruitList());
                throw new BizException(ErrorCodeEnum.COMMON_INNER_ERROR, positionInfoDTO.getName() + "岗位匹配分数重叠， 匹配需要人工解决");
            } else {
                positionInfoDTO.setUsed(i);
                positionInfoDTO.setWaited(0);
            }
        }
    }

    private CommonRepresentationRecordInsertRequest buildScoreError(String name) {
        CommonRepresentationRecordInsertRequest recordDO = new CommonRepresentationRecordInsertRequest();
        recordDO.setType(RepresentationTypeEnum.PLACEMENT.name());
        recordDO.setContent(name);

        recordDO.setBizType(PlacementRepresentationTypeEnum.SCORE.name());
        recordDO.setType(RepresentationTypeEnum.PLACEMENT.name());
        recordDO.setStatus(ProcessStatusEnum.DEALING.name());
        recordDO.setRealName("系统");
        return recordDO;
    }

    private int savePositionResult(Map<String, PlacementPositionInfoDTO> positionMap) {
        int count = 0;
        for (PlacementPositionInfoDTO positionInfoDTO : positionMap.values()) {
            for (PlacementSoldierInfoDTO soldierInfoDTO : positionInfoDTO.getRecruitList()) {
                PlacementSoldierAspirationResultDO resultDO = new PlacementSoldierAspirationResultDO();
                resultDO.setPlacementId(soldierInfoDTO.getPlacementId());
                resultDO.setBatchId(positionInfoDTO.getBatchId());
                resultDO.setSoldierId(soldierInfoDTO.getSoldierId());
                resultDO.setIdCardNo(soldierInfoDTO.getIdCardNo());
                resultDO.setRealName(soldierInfoDTO.getRealName());
                resultDO.setPositionId(positionInfoDTO.getId());
                resultDO.setStatus(PlacementAspirationResultStatusEnum.SUCCESS.name());
                placementSoldierAspirationResultService.insert(resultDO);
                log.info("志愿匹配成功：{}", resultDO);
                count++;
            }
        }
        return count;
    }


    @Override
    public BaseResponse<Integer> deletePlacementInfo(final BaseDeleteRequest deleteRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(deleteRequest, "逻辑删除PlacementInfo的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(deleteRequest.getModifierType(), "操作人类型不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getModifierId(), "操作人不能为空");
            }

            @Override
            public void executeService() {
                final Integer affectRowNum = placementInfoService.delete((String) deleteRequest.getId(), deleteRequest.getModifierType(), (String) deleteRequest.getModifierId());
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.PLACEMENT_INFO_DELETE_LOGICALLY;
            }
        });
        return baseResponse;
    }


    public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
    }
}
